package cn.bugstack.springframework.beans.factory.support;

import cn.bugstack.springframework.beans.BeansException;
import cn.bugstack.springframework.beans.factory.config.BeanDefinition;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;

import java.lang.reflect.Constructor;

/**
 * Cglib 实例化策略
 */
public class CglibSubclassingInstantiationStrategy implements InstantiationStrategy{

    /**
     * 根据给定的BeanDefinition和构造函数参数创建一个新对象实例。
     *
     * @param beanDefinition 描述待创建对象的BeanDefinition，包括类名等信息。
     * @param beanName 待创建对象的名称。
     * @param constructor 要使用的构造函数，如果为null，则使用无参构造函数。
     * @param args 传递给构造函数的参数数组。
     * @return 返回新创建的对象实例。
     * @throws BeansException 如果在实例化过程中发生错误。
     */
    @Override
    public Object instantiate(BeanDefinition beanDefinition, String beanName, Constructor constructor, Object[] args) throws BeansException {
        // 使用CGLib创建一个增强器，用于生成动态代理对象
        Enhancer enhancer = new Enhancer();
        // 设置代理对象的父类为beanDefinition指定的类
        enhancer.setSuperclass(beanDefinition.getBeanClass());
        // 设置回调函数，这里使用了一个空操作的回调，仅为了示例
        enhancer.setCallback(new NoOp() {
            @Override
            public int hashCode() {
                return super.hashCode();
            }
        });
        // 如果没有指定构造函数，则直接创建对象实例
        if (null == constructor) return enhancer.create();
        // 如果指定了构造函数，则使用指定的构造函数创建对象实例，并传入参数
        return enhancer.create(constructor.getParameterTypes(), args);
    }

}
